/*
 * Created by SharpDevelop.
 * User: kktn
 * Date: 04.07.2006
 * Time: 15:17
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using TagTool.Core;
using System.Collections.Generic;
using TagTool.GraphicTypes;

namespace TagTool.Nodes.Misc
{

	public class ObjectCacheTemplate<T> : BaseNode where T: new()
	{
		bool init = false;
		private InputSlot inData;
		
		private InputSlot reset;
		protected OutputSlot count;
		private OutputSlot outData;
		private InputSlot index;
		private OutputSlot selected;

		private double sel = 0.0;
		
		bool trigg = false;
		
		protected List<T> objectList = new List<T>();

		virtual protected T Zero
        {
        	get { return new T(); }
        }
		
		public ObjectCacheTemplate() : base()
		{
			inData = new InputSlot(this, "Data in", new T());

			reset = new InputSlot(this, "Reset", false);

			count = new OutputSlot(this, "Count", typeof(double));
			count.Value = 0.0;

			outData = new OutputSlot(this, "Data out", typeof(List<T>));
			outData.ValueTypeName = "List<" + typeof(T).Name + ">";
			outData.Value = objectList;
			
			index = new InputSlot(this, "Index", 0.0);
			index.ParseCallback = ParseHelper.ParseDouble;
			
			selected = new OutputSlot(this, "Selected", typeof(T));
			selected.Value = new T();
		}
		
		[NodeAttribute(SlotType.Input, Show = true)]
		public InputSlot InData
		{
			get { return inData; }
		}

		[NodeAttribute(SlotType.Input, Show = true)]
		public InputSlot Reset
		{
			get { return reset; }
		}

		[NodeAttribute(SlotType.Output, Show = true)]
		public OutputSlot Count
		{
			get { return count; }
		}
		
		[NodeAttribute(SlotType.Output, Show = true)]
		public OutputSlot OutData
		{
			get { return outData; }
		}
		
		[NodeAttribute(SlotType.Input, Show = true)]
		public InputSlot Index
		{
			get { return index; }
		}
		
		[NodeAttribute(SlotType.Output, Show = true)]
		public OutputSlot Selected
		{
			get { return selected; }
		}
		
		public override void Update(Object sender)
		{
			if ((bool)reset.Value || init)
			{
				objectList.Clear();
				outData.Value = objectList;
				count.Value = (double)objectList.Count;
				index.Value = (double)objectList.Count;
				selected.Value = new T();
			}
			else
			{
				if ((double)index.Value != sel)
				{
					double d = (double)index.Value;

					if (d != sel && d >= 0.0 && d < (double)objectList.Count)
					{
						sel = d;
						selected.Value = objectList[(int)d];
					}
				}
				
				if (objectList.Count == 1)
				{
					selected.Value = objectList[0];
				}
				else if (objectList.Count <= 0)
				{
					selected.Value = Zero;
				}
				
				//if ((bool)TriggerIn.Value == true && trigg != (bool)TriggerIn.Value)
				// exchanged: 25.01.2007
				if ((bool)TriggerIn.Value == true && trigg == false)
				{
					objectList.Add((T)inData.Value);
					count.Value = (double)objectList.Count;
					if (objectList.Count == 1)
					{
						selected.Value = objectList[0];
					}
					
					CastTrigger();
				}
				
				trigg = (bool)TriggerIn.Value;
			}
		}
		
		public override void Initialize() {
			init = true;
			trigg = false;
			Update(TriggerIn);
			init = false;
		}
		
	}
	
}
